package com.fxkj.cloud.drms.domain.linkage;

import com.fxkj.cloud.dbs.common.model.kv.TsKvEntry;
import com.fxkj.cloud.dbs.common.model.linkage.FxExecuteCondition;
import com.fxkj.cloud.drms.domain.ts.service.TimeseriesService;
import com.google.common.util.concurrent.*;


import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * <p>description: </p>
 * @author ww
 * @date 2025/3/28 13:48
 */
public class FxExecuteConditionFilterChain implements AnyMatchFilterChain {
    private final List<FxExecuteCondition> executeConditions;
    private final TimeseriesService timeseriesService;

    public FxExecuteConditionFilterChain(List<FxExecuteCondition> executeConditions, TimeseriesService timeseriesService) {
        this.executeConditions = executeConditions;
        this.timeseriesService = timeseriesService;
    }

    @Override
    public Boolean anyMatch(UUID deviceId, List<TsKvEntry> deviceKvs) {
        List<String> attributeKeys = executeConditions.stream().map(FxExecuteCondition::getAttributeKeys).flatMap(Collection::stream).collect(Collectors.toList());
        ListenableFuture<List<TsKvEntry>> future;
        if (!attributeKeys.isEmpty()) {
            future = timeseriesService.queryLastValueForString(deviceId, attributeKeys);
            try {
                return Futures.transformAsync(future, input -> Futures.immediateFuture(executeConditions.stream().anyMatch((executeCondition) -> executeCondition.match(deviceId, input))), MoreExecutors.directExecutor()).get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        return executeConditions.stream().anyMatch((executeCondition) -> executeCondition.match(deviceId, new ArrayList<>()));
    }
}
